//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _APPS_BUSH_PARSER_CPYTHONINTEGER_H_
#define _APPS_BUSH_PARSER_CPYTHONINTEGER_H_

#include <buola/buola.h>

namespace buola { namespace bush { namespace token {

struct CPythonInteger
{
    typedef std::wstring::const_iterator tIt;

    static bool Parse0(tIt &pB,const tIt &pE)
    {
        for(++pB;pB!=pE;++pB)
        {
            switch(*pB)
            {
            case '0':
                break;
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                return false;
            default:
                return true;
            }
        }
        return true;
    }
    
    static bool ParseDecNumber(tIt &pB,const tIt &pE)
    {
        bool lOk=false;
        for(;pB!=pE;++pB)
        {
            switch(*pB)
            {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                lOk=true;
                break;
            default:
                return lOk;
            }            
        }
        return lOk;
    }

    static bool ParseHexNumber(tIt &pB,const tIt &pE)
    {
        bool lOk=false;
        for(++pB;pB!=pE;++pB)
        {
            switch(*pB)
            {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                lOk=true;
                break;
            case 'A':
            case 'B':
            case 'C':
            case 'D':
            case 'E':
            case 'F':
                lOk=true;
                break;
            case 'a':
            case 'b':
            case 'c':
            case 'd':
            case 'e':
            case 'f':
                lOk=true;
                break;
            default:
                return lOk;
            }            
        }
        return lOk;
    }

    static bool ParseOctNumber(tIt &pB,const tIt &pE)
    {
        bool lOk=false;
        for(++pB;pB!=pE;++pB)
        {
            switch(*pB)
            {
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
                lOk=true;
                break;
            default:
                return lOk;
            }            
        }
        return lOk;
    }

    static bool ParseBinNumber(tIt &pB,const tIt &pE)
    {
        bool lOk=false;
        for(++pB;pB!=pE;++pB)
        {
            switch(*pB)
            {
            case '0':
            case '1':
                lOk=true;
                break;
            default:
                return lOk;
            }            
        }
        return lOk;
    }

    static bool Parse0Number(tIt &pB,const tIt &pE)
    {
        if(++pB==pE)
            return true; //single 0
        
        switch(*pB)
        {
        case 'o':
            return ParseOctNumber(pB,pE);
        case 'x':
            return ParseHexNumber(pB,pE);
        case 'b':
            return ParseBinNumber(pB,pE);
        case '0':
            return Parse0(pB,pE);
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        default:
            return true;
        }
    }
    
    static bool Parse(tIt &pB,const tIt &pE)
    {
        switch(*pB)
        {
        case '0':
            return Parse0Number(pB,pE);
            break;
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            return ParseDecNumber(pB,pE);
            break;
        default:
            return false;
            break;
        }
    }
};
   
/*namespace token*/ } /*namespace bush*/ } /*namespace buola*/ }

#endif
